home *** CD-ROM | disk | FTP | other *** search
- /* Listing 2. LEX.C -- A Brute-Force Lexical Analyzer */
-
- #include <stdio.h>
- #include "lex.h"
-
- char *yytext = ""; /* holds the lexeme (not \0 terminated) */
- int yyleng = 0; /* number of valid characters in lexeme */
- FILE *yyinp = stdin; /* Input FILE. */
- #define LINELEN 128 /* Maximum input-line length. */
-
- #if ( defined(DEBUG) || defined(PTRACE) )
-
- char *tokstr( token t )
- {
- switch( t )
- {
- case NO_TOKEN: return "NO_TOKEN";
- case EOI: return "EOI";
- case EQUAL: return "EQUAL";
- case ID: return "ID";
- case LP: return "LP";
- case MINUS: return "MINUS";
- case NUMBER: return "NUMBER";
- case PLUS: return "PLUS";
- case RP: return "RP";
- case SEMI: return "SEMI";
- case SLASH: return "SLASH";
- case STAR: return "STAR";
- case WHILE: return "WHILE";
- }
-
- return "UNKNOWN";
- }
- #endif
-
- /*----------------------------------------------------------------------*/
-
- static token yylex()
- {
- /* A brute-force, line oriented lexical analyzer */
-
- static char input_buf[ LINELEN ]; /* Initialized to 0's by default. */
- static char *p = input_buf; /* *p is initially '\0'. */
-
- int rval = NO_TOKEN; /* Returned token */
-
- do
- {
- if( !*p ) /* If buffer empty, */
- {
- if( !fgets(input_buf, LINELEN, yyinp) ) /* get a new line. */
- return EOI; /* End of input. */
- p = input_buf;
- }
-
- while( isspace( *p ) ) /* Skip leading white space */
- ++p;
-
- } while( !*p ); /* Until you find a nonempty line. */
-
- /* At this juncture, p is pointing at a nonspace character; either
- * at the first character on the line or at the first nonspace
- * character following the last lexeme we recognized.
- */
-
- yytext = p; /* pointer to current lexeme */
- yyleng = 1; /* default lexeme length */
-
- switch( *p++ )
- {
- case '=': rval = EQUAL; break;
- case '+': rval = PLUS; break;
- case '-': rval = MINUS; break;
- case '*': rval = STAR; break;
- case '/': rval = SLASH; break;
- case ';': rval = SEMI; break;
- case '(': rval = LP; break;
- case ')': rval = RP; break;
- default:
- if( isdigit(*yytext) )
- {
- for(; isdigit(*p); ++p, ++yyleng )
- ;
- rval = NUMBER;
- }
- else if( isalpha(*yytext) )
- {
- for(; isalnum(*p); ++p, ++yyleng )
- ;
-
- rval = !strncmp("while", yytext, yyleng) ? WHILE
- : ID;
- }
- else
- {
- fprintf(stderr,"Ignoring bad input char. (%c)\n", *yytext);
- exit(1);
- }
- }
- # ifdef DEBUG
- printf("yylex returning %s (%1.*s)\n", tokstr(rval), yyleng, yytext);
- # endif
-
- return rval;
- }
- /*------------------------------------------------------------------*/
- static token Lookahead = NO_TOKEN;
-
- int match( token t )
- {
- if( Lookahead == NO_TOKEN )
- Lookahead = yylex();
-
- return Lookahead == t;
- }
- /*------------------------------------------------------------------*/
- void advance()
- {
- #ifdef PTRACE /* Debugging diagnostic, print */
- /* current lexeme before advancing */
- extern int rdepth(void); /* declared in topdown.c */
-
- printf("%*s%s (%1.*s)\n", rdepth(), "", tokstr(Lookahead),
- yyleng, yytext );
- #endif;
-
- Lookahead = yylex();
- }